package org.opens.javaskill.design.apply;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.stream.IntStream;

/**
 * @Date 2020/9/20 20:47
 * @Created by 99126
 */
public class CountDownPattern {

    public static void main(String[] args) {

    }

}

/**
 * 说明:
 * <pre>
 *     1. 这个是使用jdk提供的countDown控制器.
 * </pre>
 */
class JdkCountDown {

    private static final Random random = new Random(System.currentTimeMillis());

    public static void main(String[] args) throws InterruptedException {

        final CountDownLatch latch = new CountDownLatch(5);

        // the first phase
        System.out.println("准备多线程处理任务");

        IntStream.rangeClosed(1, 5).forEach(i -> {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " working");
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 标记结束
                latch.countDown();
            }, "t" + i).start();
        });
        // 如果没有全部结束, 就等着, 将会实现和Thread执行join方法之后实现相同的结果.
        latch.await();
        System.out.println("多线程任务全部结束, 准备二阶段任务");

        System.out.println("finish");
    }

}

/**
 * 说明:
 * <pre>
 *     1. 这个是自己实现的countDown控制器.
 * </pre>
 */
class MyCountDown {

    private static final Random random = new Random(System.currentTimeMillis());

    /**
     * 定义任务总量
     */
    private final int total;

    private int counter;

    public MyCountDown(int total) {
        this.total = total;
    }

    public void down() {
        synchronized (this) {
            this.counter++;
            this.notifyAll();
        }
    }

    public void await() throws InterruptedException {
        synchronized (this) {
            while (counter != total) {
                this.wait();
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        final MyCountDown latch = new MyCountDown(5);

        // the first phase
        System.out.println("准备多线程处理任务");

        IntStream.rangeClosed(1, 5).forEach(i -> {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " working");
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 标记结束
                latch.down();
            }, "t" + i).start();
        });
        // 如果没有全部结束, 就等着, 将会实现和Thread执行join方法之后实现相同的结果.
        latch.await();
        System.out.println("多线程任务全部结束, 准备二阶段任务");

        System.out.println("finish");
    }

}